package com.aaa.sts.service.impl;

import com.aaa.common.entity.Store;
import com.aaa.common.entity.StoreUser;
import com.aaa.common.util.CustomException;
import com.aaa.common.util.ResultStatus;
import com.aaa.common.util.TokenUtil;
import com.aaa.common.vo.Page;
import com.aaa.common.vo.StoreRegisterStatisticsVO;
import com.aaa.sts.dao.StoreDao;
import com.aaa.sts.dao.StoreUserDao;
import com.aaa.sts.service.RemoteRoleService;
import com.aaa.sts.service.StoreService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * (Store)表服务实现类
 *
 * @author makejava
 * @since 2025-09-16 09:55:23
 */
@Service("storeService")
public class StoreServiceImpl implements StoreService {
    private static final Logger log = LoggerFactory.getLogger(StoreServiceImpl.class);
    @Resource
    private StoreDao storeDao;
    @Resource
    private HttpServletRequest request;
    @Resource
    private RemoteRoleService remoteRoleService;
    @Resource
    private StoreUserDao storeUserDao;

    @Override
    public String selectStoreName(Integer storeId) {
        return storeDao.selectStoreName(storeId);
    }
    /**
     * 查询店铺绑定人数
     * @return
     */
    @Override
    public int queryByUserId(Integer storeId) {
        List<Store> storeList = storeDao.queryByUserId(storeId);
        int count =(int) storeList.stream().count();
        return count;
    }

    @Override
    public List<Store> selectAllStore(String storeName) {
        return storeDao.selectAllStore(storeName);
    }

    @Override
    public List<Store> selectStoreByStoreIdAndUserId(Integer storeId, Integer userId) {
        return storeDao.selectStoreByStoreIdAndUserId(storeId, userId);
    }

    @Override
    public List<Store> selectStoreById() {
        String userId = TokenUtil.getUserId(request);

        return storeDao.selectStoreById(Integer.valueOf(userId));
    }

    /**
     * 按月份统计商家入驻数量
     *
     * @return 包含月份和对应入驻数的统计列表
     */
    @Override
    public List<StoreRegisterStatisticsVO> selectStoreNumberByMonth() {
        return storeDao.selectStoreNumberByMonth();
    }

    /**
     * 查询商家入驻总数
     *
     * @return 商家总数
     */
    @Override
    public Integer selectAllStoreNumber() {
        return storeDao.selectAllStoreNumber();
    }

    @Override
    public List<Store> getStoresInRectangle(Float minLng, Float maxLng, Float minLat, Float maxLat) {
        // 查询矩形区域内的店铺
        List<Store> stores = storeDao.selectStoresInRectangle(minLng, maxLng, minLat, maxLat);

        // 计算矩形区域中心点坐标（用于计算距离）
        double centerLng = (minLng + maxLng) / 2.0;
        double centerLat = (minLat + maxLat) / 2.0;

        // 为每个店铺计算到中心点的距离（单位：公里）
        for (Store store : stores) {
            double distance = calculateDistance(
                    centerLng, centerLat,
                    store.getLongitude(), store.getLatitude()
            );
            store.setStoreDistance(distance);
        }

        return stores;
    }

    @Override
    public List<Store> getStoresInRectangleAndAddress(
            Float minLng, Float maxLng, Float minLat, Float maxLat, String address) {
        address = address.replace("-","");
            // 调用Repository层同时按地理范围和地址查询
        List<Store> stores = storeDao.selectByRectangleAndAddress(
                minLng, maxLng, minLat, maxLat, address);

        // 计算矩形区域中心点坐标（用于计算距离）
        double centerLng = (minLng + maxLng) / 2.0;
        double centerLat = (minLat + maxLat) / 2.0;

        // 为每个店铺计算到中心点的距离（单位：公里）
        for (Store store : stores) {
            double distance = calculateDistance(
                    centerLng, centerLat,
                    store.getLongitude(), store.getLatitude()
            );
            store.setStoreDistance(distance);
        }

        return stores;
    }
    /**
     * 使用Haversine公式计算地球表面两点间的距离（单位：公里）
     * @param lng1 点1经度
     * @param lat1 点1纬度
     * @param lng2 点2经度
     * @param lat2 点2纬度
     * @return 两点间距离（公里）
     */
    private double calculateDistance(double lng1, double lat1, double lng2, double lat2) {
        // 地球半径（公里）
        final double R = 6371.0;

        // 将角度转换为弧度
        double radLat1 = Math.toRadians(lat1);
        double radLat2 = Math.toRadians(lat2);
        double radLng1 = Math.toRadians(lng1);
        double radLng2 = Math.toRadians(lng2);

        // 计算经纬度差值
        double deltaLat = radLat2 - radLat1;
        double deltaLng = radLng2 - radLng1;

        // Haversine公式
        double a = Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2)
                + Math.cos(radLat1) * Math.cos(radLat2)
                * Math.sin(deltaLng / 2) * Math.sin(deltaLng / 2);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

        // 计算距离（公里）
        double distance = R * c;

        return Double.parseDouble(String.format("%.2f", distance));
    }

    /**
     * 通过ID查询单条数据
     *
     * @param storeId 主键
     * @return 实例对象
     */
    @Override
    public Store queryById(Integer storeId) {
        return this.storeDao.queryById(storeId);
    }


    /**
     * 查询当前登录用户所属角色的店铺
     *
     * @param
     * @return
     */
    /*@Override
    public PageInfo selectMySelfStore(StoreQueryDTO queryDTO) {// 1. 参数校验（保持不变）
        String userIdStr = TokenUtil.getUserId(request);
        if (userIdStr == null) {
            throw new RuntimeException("用户未登录");
        }
        Integer userId = Integer.valueOf(userIdStr);
        log.info("========用户ID：{}", userId);

        // 2. 获取角色（增加异常处理）
        List<String> roleKeyList = null;
        try {
            roleKeyList = remoteRoleService.queryRoleKey(userId);
        } catch (Exception e) {
            //log.error("获取用户角色失败", e);
            throw new RuntimeException("获取角色信息异常");
        }
        log.info("========角色列表：{}", roleKeyList);
        //List<String> roleKeys = roleKeyList.
        if (CollectionUtils.isEmpty(roleKeyList)) {
            throw new RuntimeException("用户无有效角色");
        }
        // 3. 角色判断（简化逻辑）
        String roleKey = roleKeyList.contains("guanliyuan") ? "guanliyuan" :
                roleKeyList.contains("laoban") ? "laoban" : null;
        log.info("========角色：{}", roleKey);
        if (roleKey == null) {
            throw new RuntimeException("无权查看店铺");
        }
        if (queryDTO == null || queryDTO.getPageNo() == null || queryDTO.getPageSize() == null) {
            throw new CustomException(ResultStatus.PARAM_NOT_EMPTY.getReturnCode(),ResultStatus.PARAM_NOT_EMPTY.getReturnMessage());
        }
        // 4. 分页查询
        PageHelper.startPage(queryDTO.getPageNo(), queryDTO.getPageSize());
        List<Store> stores = storeDao.selectMySelfStore(roleKey, userId, queryDTO);
        //List<Store> stores = storeDao.selectMySelfStore(roleKey, userId, page.getData());
        log.info("========查询结果：{}", stores);
        return new PageInfo<>(stores);
    }
*/


    /**
     * 分页查询
     *
     * @param page 筛选条件
     * @return 查询结果
     */
    @Override
    public PageInfo queryByPage(Page<Store> page) {
        Integer userId = Integer.valueOf(TokenUtil.getUserId(request));
        log.info("========用户ID：{}", userId);
        //分页操作  分页参数一定要进行传递
        if (page == null || page.getPageNo() == null || page.getPageNo() == 0 || page.getPageSize() == null || page.getPageSize() == 0) {
            //进行业务编写时，可以抛出自定义异常
            throw new CustomException(ResultStatus.PARAM_NOT_EMPTY.getReturnCode(),
                    ResultStatus.PARAM_NOT_EMPTY.getReturnMessage());
        }
        PageHelper.startPage(page.getPageNo(), page.getPageSize());
        //获取查询对象
        //Store store = page.getData();
        Store store = page.getData() != null ? page.getData() : new Store();
        List<String> roleKeyList = remoteRoleService.queryRoleKey(userId);
        log.info("========角色列表：{}", roleKeyList);
        // 3. 角色判断（简化逻辑）
        String roleKey = roleKeyList.contains("guanliyuan") ? "guanliyuan" :
                roleKeyList.contains("laoban") ? "laoban" : null;
        log.info("========角色：{}", roleKey);
        if (roleKey.equals("laoban")){
            store.setUserId(userId);
        }
        return new PageInfo(storeDao.queryAllByLimit(store));
    }

    @Override
    public List<Store> selectMyStore(Store  store) {
        return storeDao.queryAllByLimit(store);
    }

    /**
     * 新增数据
     *
     * @param store 实例对象
     * @return 实例对象
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Store insert(Store store) {
        store.setCreateBy(TokenUtil.getUserName(request));
        this.storeDao.insert(store);
        //获取当前用户的ID
        String userId = TokenUtil.getUserId(request);
        //创建店铺用户关系对象
        StoreUser storeUser = new StoreUser();
        storeUser.setUserId(Integer.valueOf(userId));
        storeUser.setStoreId(store.getStoreId());
        //在店铺用户关系表中添加数据
        storeUserDao.insert(storeUser);

        return store;
    }

    /**
     * 修改数据
     *
     * @param store 实例对象
     * @return 实例对象
     */
    @Override
    public Store update(Store store) {
        store.setUpdateBy(TokenUtil.getUserName(request));
        this.storeDao.update(store);
        return this.queryById(store.getStoreId());
    }

    /**
     * 通过主键删除数据
     *
     * @param storeId 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Integer storeId) {
        return this.storeDao.deleteById(storeId) > 0;
    }
}
